package com.cls.system.controller;

import com.cls.business.entity.ApplicantInfo;
import com.cls.business.service.IApplicantInfoService;
import com.cls.common.entity.MyConstant;
import com.cls.common.service.RedisService;
import com.cls.system.entity.Expert;
import com.cls.system.service.IExpertService;
import com.github.pagehelper.PageInfo;
import com.cls.common.annotation.ControllerEndpoint;
import com.cls.common.controller.BaseController;
import com.cls.common.entity.ResponseVO;
import com.cls.common.entity.QueryRequest;
import com.cls.common.exception.MyException;
import com.cls.common.utils.Md5Util;
import com.cls.system.entity.User;
import com.cls.system.service.IUserService;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.wuwenze.poi.ExcelKit;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;

/**
 * @author WeiMaomao
 */
@Slf4j
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("user")
public class UserController extends BaseController {

    private final IUserService userService;
    private final IExpertService expertService;
    private final IApplicantInfoService applicantInfoService;
    private final RedisService redisService;

    @PostMapping("resetPass")
    @ResponseBody
    public ResponseVO resetPass(@NotBlank(message = "{required}") String mobile,
                                @NotBlank(message = "{required}") Long smsCode,
                                @NotBlank(message = "{required}") String newPass,
                                @NotBlank(message = "{required}") String newPass2) {
        Long smsCodeRedis = (Long) redisService.get(mobile);
        if (smsCodeRedis == null) {
            return ResponseVO.failure("邮箱验证码已过期！");
        }
        if (!smsCodeRedis.equals(smsCode)) {
            return ResponseVO.failure("邮箱验证码不正确！");
        }
        if (!StringUtils.equals(newPass, newPass2)) {
            return ResponseVO.failure("两次密码输入不一致！");
        }
        User user = getCurrentUser();
        userService.updatePassword(user.getUsername(), newPass);
        return ResponseVO.success();
    }

    /**
     * 更新密码
     *
     * @return
     */
    @PostMapping("updatePass")
    @ResponseBody
    public ResponseVO updatePass(@NotBlank(message = "{required}") String oldPass,
                                 @NotBlank(message = "{required}") String newPass,
                                 @NotBlank(message = "{required}") String newPass2) {
        User user = getCurrentUser();
        if (!StringUtils.equals(user.getPassword(), Md5Util.encrypt(user.getUsername(), oldPass))) {
            return ResponseVO.failure("原密码不正确");
        }
        if (!StringUtils.equals(newPass, newPass2)) {
            return ResponseVO.failure("两次密码输入不一致！");
        }
        userService.updatePassword(user.getUsername(), newPass);
        return ResponseVO.success();
    }


    @PostMapping("updateEmail")
    @ResponseBody
    public ResponseVO updateMobile(String email, Long smsCode) {
        Object emailCodeRedis = redisService.get(email);
        if (emailCodeRedis == null) {
            return ResponseVO.failure("邮箱验证码已过期！");
        }
        emailCodeRedis = Long.valueOf(emailCodeRedis.toString());
        if (!emailCodeRedis.equals(smsCode)) {
            return ResponseVO.failure("邮箱验证码不正确！");
        }
        Subject subject = super.getSubject();
        User currentUser = super.getCurrentUser();
        //申请人角色
        if (subject.hasRole(MyConstant.REGISTER_ROLE_NAME)) {
            ApplicantInfo applicantInfo = applicantInfoService.findByUserId(currentUser.getUserId());
            applicantInfo.setEmail(email);
            applicantInfoService.updateById(applicantInfo);
        }//专家角色
        else if (subject.hasRole(MyConstant.EXPERT_ROLE_NAME)) {
            Expert expert = expertService.findByUserId(currentUser.getUserId());
            expert.setEmail(email);
            expertService.updateById(expert);
        }
        currentUser.setEmail(email);
        userService.updateById(currentUser);
        return ResponseVO.success();
    }


    @GetMapping("{username}")
    public User getUser(@NotBlank(message = "{required}") @PathVariable String username) {
        return this.userService.findUserDetailList(username);
    }

    @GetMapping("check/{username}")
    public boolean checkUserName(@NotBlank(message = "{required}") @PathVariable String username, String userId) {
        return this.userService.findByName(username) == null || StringUtils.isNotBlank(userId);
    }

    @GetMapping("list")
    @RequiresPermissions("user:view")
    public ResponseVO userList(User user, QueryRequest request) {
        PageInfo<User> userDetailList = this.userService.findUserDetailList(user, request);
        return ResponseVO.success(userDetailList);
    }

    @PostMapping
    @RequiresPermissions("user:add")
    @ControllerEndpoint(operation = "新增用户", exceptionMessage = "新增用户失败")
    public ResponseVO addUser(@Valid User user) {
        this.userService.createUser(user);
        return ResponseVO.success();
    }

    @PostMapping("delete/{userIds}")
    @RequiresPermissions("user:delete")
    @ControllerEndpoint(operation = "删除用户", exceptionMessage = "删除用户失败")
    public ResponseVO deleteUsers(@NotBlank(message = "{required}") @PathVariable String userIds) {
        String[] ids = userIds.split(StringPool.COMMA);
        this.userService.deleteUsers(ids);
        return ResponseVO.success();
    }

    @PostMapping("pwdReset/{userId}")
    @RequiresPermissions("user:update")
    @ControllerEndpoint(operation = "用户重置密码", exceptionMessage = "用户重置密码失败")
    public ResponseVO pwdReset(@NotBlank(message = "{required}") @PathVariable String userId) {
        this.userService.pwdReset(userId);
        return ResponseVO.success();
    }

    @PostMapping("update")
    @RequiresPermissions("user:update")
    @ControllerEndpoint(operation = "修改用户", exceptionMessage = "修改用户失败")
    public ResponseVO updateUser(@Valid User user) {
        if (user.getUserId() == null) {
            throw new MyException("用户ID为空");
        }
        this.userService.updateUser(user);
        return ResponseVO.success();
    }

    @PostMapping("password/reset/{usernames}")
    @RequiresPermissions("user:password:reset")
    @ControllerEndpoint(exceptionMessage = "重置用户密码失败")
    public ResponseVO resetPassword(@NotBlank(message = "{required}") @PathVariable String usernames) {
        String[] usernameArr = usernames.split(StringPool.COMMA);
        this.userService.resetPassword(usernameArr);
        return ResponseVO.success();
    }

    @PostMapping("password/update")
    @ControllerEndpoint(exceptionMessage = "修改密码失败")
    public ResponseVO updatePassword(
            @NotBlank(message = "{required}") String oldPassword,
            @NotBlank(message = "{required}") String newPassword) {
        User user = getCurrentUser();
        if (!StringUtils.equals(user.getPassword(), Md5Util.encrypt(user.getUsername(), oldPassword))) {
            throw new MyException("原密码不正确");
        }
        userService.updatePassword(user.getUsername(), newPassword);
        return ResponseVO.success();
    }

    @GetMapping("avatar/{image}")
    @ControllerEndpoint(exceptionMessage = "修改头像失败")
    public ResponseVO updateAvatar(@NotBlank(message = "{required}") @PathVariable String image) {
        User user = getCurrentUser();
        this.userService.updateAvatar(user.getUsername(), image);
        return ResponseVO.success();
    }

    @PostMapping("theme/update")
    @ControllerEndpoint(exceptionMessage = "修改系统配置失败")
    public ResponseVO updateTheme(String theme, String isTab) {
        User user = getCurrentUser();
        this.userService.updateTheme(user.getUsername(), theme, isTab);
        return ResponseVO.success();
    }

    @PostMapping("profile/update")
    @ControllerEndpoint(exceptionMessage = "修改个人信息失败")
    public ResponseVO updateProfile(User user) throws MyException {
        User currentUser = getCurrentUser();
        user.setUserId(currentUser.getUserId());
        this.userService.updateProfile(user);
        return ResponseVO.success();
    }

    @GetMapping("excel")
    @RequiresPermissions("user:export")
    @ControllerEndpoint(exceptionMessage = "导出Excel失败")
    public void export(QueryRequest queryRequest, User user, HttpServletResponse response) {
        List<User> users = this.userService.findUserDetailList(user, queryRequest).getList();
        ExcelKit.$Export(User.class, response).downXlsx(users, false);
    }
}
